home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
gigo0714.zip
/
LISTSERV.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-14
|
21KB
|
767 lines
/*
* LISTSERV
*
* Sample program that takes a GIGO function request file (FUNCTION.REQ), checks
* it, and then modifies the appropriate .ML files (for mailing lists).
*
* Jason Fesler December, 1990 jfesler@wmeonlin.sacbbx.com
*/
/*
* Modification History:
*
* Date By Description
* 2/21/95 David Gibbs Added recognition of SET & REVIEW command, both commands inform requester that commands are not implemented.
* 2/3/95 David Gibbs Changed command recognition from 1 character to 3.
* 4/25/94 David Gibbs Added basic activity logging
* 12/30/95 Jason Fesler Added in a "confirmation" process
*
*/
/*
* For simplicity sake, I include everything, so that I don't have any
* problems with the compiler knowing what I am talking about.
*/
#include <time.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <process.h>
#include <share.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
#include <ctype.h>
#include <direct.h>
#include <dos.h>
#include <stdarg.h>
/*
* Global variables are usually a bad programming practice. However, I don't
* give a damn.. :-)
*
*/
extern unsigned int _stklen = 10000;
//Borland style stack declaration,
//ymmv
struct headers {
char Apparently_To[256];
char Apparently_From[256];
char To[256];
char From[256];
char Subject[256];
} header;
char wholeparm[512] = "";
FILE *infile, *outfile, *file;
int amihere = 0;
int amiheremsg = 1;
int useconf = 1;
enum commands {
HELP, INDEX, FAQ, SUBSCRIBE, UNSUBSCRIBE, QUERY, QUIT,
DISCONNECT, SET, SIG, REVIEW, ADDRESS, CONFIRM, UNKNOWN
};
void logproblem(char *cmd, char *parm);
/*
* cmpcopy looks to see if string at <source> compares to the string at
* <token>. If it does, the parameters after <token> are going to be copied
* to <dest>.
*/
void
cmpcopy(char *token, char *source, char *dest)
{
if (!strncmp(source, token, strlen(token))) {
source += strlen(token);
//get past the token itself
while (*source == ' ')
source++;
//get past the spaces
strcpy(dest, source);
}
}
/*
* readheaders reads in the top part of the file until it reaches a newline
* character.
*
*/
void
readheaders(void)
{
char line[1024] = " ";
memset(&header, 0, sizeof(headers));
while ((*line) && (!feof(infile))) {
/* remember, GIGO stands for garbage in, garbage out. */
memset(line, 0, sizeof(line));
fgets(line, sizeof(line) - 1, infile);
/* fgets includes the line terminator; we need to remove it. */
if (*line)
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = 0;
if (*line)
if (line[strlen(line) - 1] == '\r')
line[strlen(line) - 1] = 0;
if (!*line)
continue; /* We got a blank line, or an eof */
cmpcopy("Apparently-To:", line, header.Apparently_To);
cmpcopy("Apparently-From:", line, header.Apparently_From);
cmpcopy("To:", line, header.To);
cmpcopy("From:", line, header.From);
cmpcopy("Subject:", line, header.Subject);
}
}
void
show_internal_help()
{
fprintf(outfile,
"Simple help instructions for the GIGO listserv processor..\n"
"----------------------------------------------------------\n"
"HELp (or ?) This help information\n"
"CONFIRM number Submits confirmation number\n"
"INDex Shows the list of available lists\n"
"FAQ listname Shows the FAQ (info) file for listname\n"
"SUBscribe listname Subscribes to listname\n"
"UNSubscribe listname Unsubscribes to listname\n"
"QUEry Query the various lists to see which you are on\n"
"\n"
"DISconnect Disconnects from ALL lists on this server\n"
"\n"
"Commands may be abbreviated down to 3 characters.\n"
"\n"
);
}
/* show_file dumps the file to the reply. If it does not exist, returns a 1. */
int
show_file(char *filename)
{
//1 = error, 0 = noerror
FILE * hfile;
char buf[256];
int c;
hfile = fopen(filename, "rt");
if (!hfile) {
sprintf(buf,"Unable to show_file(\"%s\"): %s",
filename,strerror(errno));
logproblem(buf,"");
return 1;
}
while (!feof(hfile)) {
c = fgetc(hfile);
fputc(c, outfile);
}
fclose(file);
return 0;
}
/*
* Shows the faq file for filename (filename.FAQ). If it does not exist, it
* will print a message to that effect.
*/
void
show_faq(char *filename)
{
char buf[256];
sprintf(buf, "%s.faq", filename);
if (show_file(buf))
fprintf(outfile, "Sorry, no FAQ file for %s.\n", filename);
}
/*
* Attempts to dump LISTSERV.HLP to the reply; if that doesn't work, then
* shows the internal help file instead.
*/
void
process_help(void)
{
if (show_file("LISTSERV.HLP"))
show_internal_help();
}
unsigned long getcrc(char *buf);
void subscribe(char *filename, int unsub);
void
startsubscribe(char *filename)
{
char bigbuf[1024];
FILE *newfile;
int found = 0;
unsigned long c;
time_t t;
errno = 0;
if (!strchr(header.Apparently_From, '@')) {
fprintf(outfile, "SUB/UNSUB commands require a valid internet style address.\n"
"Your address appears to be %s .. \n", header.Apparently_From);
return;
}
errno = 0;
newfile = fopen("listserv.con", "at");
if (!newfile)
newfile = fopen("listserv.con", "wt");
if (!newfile) {
fprintf(outfile, "Could not create confirmation file\n", filename);
return;
}
fprintf(outfile, "-------------------------------------------------------------\n");
fprintf(outfile, "You are in the process of being subscribed to list %s.\n", filename);
fprintf(outfile, "Following will be a confirmation number; you will need\n");
fprintf(outfile, "to send back the following to finish subscribing yourself\n");
fprintf(outfile, "to the list.\n");
fprintf(outfile, "\nSend back the following:\n\n");
time(&t);
sprintf(bigbuf, "%s %s %lu", filename, header.Apparently_From, t);
c = getcrc(bigbuf);
fprintf(outfile, " confirm %08lx\n\n", c);
fprintf(newfile, "%s %08lx\n", bigbuf, c);
fprintf(outfile, "If you did not send a message to subscribe, you don't have to\n");
fprintf(outfile, "do anything. Otherwise, please send this message back as soon\n");
fprintf(outfile, "as possible, in order to finish subscribing you to list %s.\n", filename);
fprintf(outfile, "-------------------------------------------------------------\n");
fclose(newfile);
}
void
finishconfirm(char *text)
{
FILE *confile;
char filename[256] = "";
char whofrom[256] = "";
char crcval[256] = "";
char timestarted[256] = "";
char oldfrom[1024] = "";
char line[1024];
char *p, *p1, *p2, *p3, *p4;
/* text should be just the confirmation number */
if (!text)
text = "";
if (text[0] == 0) {
fprintf(outfile, "You need to specify a confirmation number.\n");
return;
}
fprintf(outfile, "Looking for confirmation number %s\n", text);
strcpy(oldfrom, header.Apparently_From);
confile = fopen("listserv.con", "rt");
if (!confile) {
notfound:
fprintf(outfile, "You are not currently in the confirmation file.\n");
fprintf(outfile, "Please send a SUBSCRIBE listname message to start\n");
fprintf(outfile, "the subscription process.\n");
return;
}
while (!feof(confile)) {
memset(line, 0, sizeof(line));
fgets(line, sizeof(line), confile);
if (p = strpbrk(line, "\r\n"))
*p = 0;
p1 = strtok(line, " ");
p2 = strtok(NULL, " ");
p3 = strtok(NULL, " ");
p4 = strtok(NULL, " ");
if (!p4)
continue;
if (stricmp(p4, text) == 0) {
strcpy(filename, p1);
st